﻿//++
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
// Module Name:
//
//    PeopleControl.cs
//
// Abstract:
//
//    Implementation of UI to select names for the "people" condition of a rule.
//    
//--

using System;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using Microsoft.Office.Interop.Outlook;

namespace Microsoft.EnhancedReminders.OutlookAddIn
{
    /// <summary>
    /// Interaction logic for PeopleControl.xaml
    /// </summary>
    public partial class PeopleControl : UserControl
    {
        private Collection<ContactInfo> _contacts;

        /// <summary>
        /// Constructor.
        /// </summary>
        public PeopleControl()
        {
            InitializeComponent();
        }

        /// <summary>
        /// Initialize the control with a list of names.
        /// </summary>
        /// <param name="contacts">The initial list of names to populate the control with.</param>
        public void Initialize(Collection<ContactInfo> contacts)
        {
            Debug.Assert(contacts != null, "contacts");

            _contacts = contacts;

            DisplayNames();
        }

        /// <summary>
        /// Displays a comma-separated list of names in the text box or "Add names" if 
        /// the list is empty.
        /// </summary>
        private void DisplayNames()
        {
            namesHyperLink.Inlines.Clear();

            if (ListIsEmpty)
            {
                namesHyperLink.Inlines.Add(Properties.Resources.RulesDialogNameChooserEmptyList);
                return;
            }

            StringBuilder displayNames = new StringBuilder();

            for (int i = 0; i < _contacts.Count; i++)
            {
                displayNames.Append(_contacts[i].Name);
                if (i < _contacts.Count - 1)
                {
                    displayNames.Append(Properties.Resources.RulesDialogNameChooserSeparator);
                }
            }

            namesHyperLink.Inlines.Add(displayNames.ToString());
        }

        /// <summary>
        /// True if the list of names is empty; false otherwise.
        /// </summary>
        private bool ListIsEmpty
        {
            get
            {
                Debug.Assert(_contacts != null, "_contacts");

                return _contacts.Count == 0;
            }
        }

        /// <summary>
        /// True if the list of names is valid and can be saved.
        /// </summary>
        public bool IsValid
        {
            get
            {
                return !ListIsEmpty;
            }
        }

        /// <summary>
        /// Launches the Outlook select names dialog, allowing the user to select names from the
        /// global address list or from personal contacts.  The names selected by this dialog are
        /// displayed in the names list.
        /// </summary>
        private void LaunchOutlookAddressBook()
        {
            Debug.Assert(_contacts != null, "_contacts");

            SelectNamesDialog snd = Globals.ThisAddIn.Application.Session.GetSelectNamesDialog();
            snd.SetDefaultDisplayMode(OlDefaultSelectNamesDisplayMode.olDefaultDelegates);
            snd.Caption = Properties.Resources.RulesDialogNameChooserCaption;
            snd.ToLabel = Properties.Resources.RulesDialogNameChooserNamesLabel;

            // Populate the list of names that will appear in the select names dialog.  Each recipient 
            // instance is created using the e-mail alias if available.  For contacts in
            // the global address list (GAL) the alias should be available, but for personal contacts this
            // will be null.  Note that the reason for using the alias where possible is that this
            // will resolve (as it needs to be unique within the GAL), whereas the name may
            // not resolve if other entries have the same name.
            foreach (ContactInfo contact in _contacts)
            {
                Recipient recipient = snd.Recipients.Add(String.IsNullOrEmpty(contact.Alias) ? contact.Name : contact.Alias);
                recipient.Resolve(); // Resolve the recipient so it appears underlined in the select names dialog.
            }

            if (!snd.Display())
            {
                return; // Select names dialog was cancelled.
            }

            // Update the list of names with those selected by the select names dialog.
            _contacts.Clear();

            for (int i = 1; i <= snd.Recipients.Count; i++)
            {
                Recipient recipient = snd.Recipients[i];

                string alias =
                    recipient.AddressEntry != null &&
                    recipient.AddressEntry.GetExchangeUser() != null ?
                       alias = recipient.AddressEntry.GetExchangeUser().Alias :
                       null;

                _contacts.Add(new ContactInfo(alias, recipient.EntryID, recipient.Name));
            }

            DisplayNames();
        }

        /// <summary>
        /// Handler for names list hyperlink being clicked.
        /// </summary>
        private void NamesHyperLinkClicked(object sender, RoutedEventArgs e)
        {
            LaunchOutlookAddressBook();
        }
    }
}
